#pragma once
#include "Nervus.h"
#include "TrainingCaseDB.h"

class CNervusMap
{
public:
	CNervusMap(void)
	{
		for( int i=0; i<NERVUS_MAP_WIDTH; i++ )
			for( int j=0; j<NERVUS_MAP_DEPTH; j++ )
				m_pNervusPool[i][j] = NULL;
	};
	~CNervusMap(void)
	{
		for( int i=0; i<NERVUS_MAP_WIDTH; i++ )
			for( int j=0; j<NERVUS_MAP_DEPTH; j++ )
				if( m_pNervusPool[i][j] )
					delete m_pNervusPool[i][j];
	};

	void CreateNervusAtPos( NervusPOS pos )
	{
		m_pNervusPool[ pos.nColumn ] [ pos.nRow ] = new CNervus();

		m_pNervusPool[ pos.nColumn ] [ pos.nRow ]->SetPosition( pos );
	};

	bool ConnectNervus( NervusPOS posSource, int nSourcePinIdx, NervusPOS posTarget )
	{
		return m_pNervusPool[ posSource.nColumn ] [ posSource.nRow ]->ConnectNervus( 
			nSourcePinIdx, 
			m_pNervusPool[ posTarget.nColumn ] [ posTarget.nRow ] );
	};

	bool DisconnectNervus( NervusPOS posSource, int nSourcePinIdx )
	{
		return m_pNervusPool[ posSource.nColumn ] [ posSource.nRow ]->CutConnection( nSourcePinIdx );
	};

	CNervus *GetNervus( int nColumn, int nRow )
	{
		return m_pNervusPool[ nColumn ][ nRow ];
	};

	void ProcessSignal( void );

private:
	CNervus *m_pNervusPool[NERVUS_MAP_WIDTH][NERVUS_MAP_DEPTH];
};

typedef struct _NervusLink{
	NervusPOS posSource;
	int nSourcePinIdx;
	NervusPOS posTarget;
} NervusLink;

class CeBrain
{
public:
	CeBrain(void);
	~CeBrain(void);

	void BuildNervusMap( void );
	void ClearNervusMap( void );
	float RunAllTrainingCase( double tryValue );
	bool RunTrainingCase( int nIdx );
	void ChangeNervusConnection( void );

	void SetNervusValues( NervusValue* pValues, int nCount )
	{
		m_pNervusValues = pValues;
		m_nNervusValuesCount = nCount;
	};

	void SaveNervusMap( void );
	void LoadNervusMap( void );

private:
	CNervusMap *m_pNervusMap;
	CNervusAntenna m_pinInput[ INPUT_SIGNAL_COUNT ];
	CNervusAntenna m_pinOutput[ OUTPUT_SIGNAL_COUNT ];
	CTrainingCaseDB *m_pTrainingCaseDB;
	int m_nOutputSignal[ OUTPUT_SIGNAL_COUNT ];
	NervusValue* m_pNervusValues;
	int m_nNervusValuesCount;
};

